package org.alvin.gencode.showdoc;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.alvin.gencode.utils.Utils;
import org.alvin.gencode.utils.VelocityUtil;
import org.alvin.mini_inject.annotations.MiniComponent;
import org.apache.velocity.app.VelocityEngine;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@MiniComponent
public class ShowDocApiService {

    public static void genCode(String showDocApiUrl, String itemId, String tempDir, String author, String outDir) throws Exception {
        String dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String url = showDocApiUrl.concat(itemId);
        List<ShowDocApiBean> apis = Lists.newArrayList();
        Document document = Jsoup.connect(showDocApiUrl.concat(itemId)).get();
        Elements elements = document.getElementsByAttributeValue("role", "menuitem");
        new File(outDir).mkdirs();
        //开始生成
        VelocityEngine fileEngine = VelocityUtil.fileVelocityEngine(tempDir);
        for (int i = 2; i < elements.size(); i++) {
            Element element = elements.get(i);
            Element menuNode = element.getElementsByTag("a").get(0);
            String tempUrl = showDocApiUrl.concat(menuNode.attr("href"));
            System.out.println(tempUrl);
            if (url.equals(tempUrl)) {
                continue;
            }
            Document doc = Jsoup.connect(showDocApiUrl.concat(menuNode.attr("href"))).get();
            Element editorElement = doc.getElementById("editor-md");
            Elements infoEls = editorElement.getElementsByTag("ul");
            System.out.println(infoEls.size());
            String text = infoEls.get(0).text();
            String requestUrl = infoEls.get(1).text();
            Elements tables = editorElement.getElementsByTag("table");
            int index = 0;
            if (tables.size() > 2) {
                index = 1;
            }
            List<ShowDocRequestBean> requestParams = parseRequestParams(tables.get(index++));

            String responseExample = editorElement.getElementsByTag("code").text();
            List<ShowDocResponseBean> responseParams = parseResponseParams(tables.get(index));
            ShowDocApiBean api = new ShowDocApiBean();
            api.setTitle(text);
            api.setFillPath(requestUrl);
            api.setUrl(requestUrl.substring(requestUrl.lastIndexOf("/") + 1));
            api.setClassName(Utils.firstUppercase(api.getUrl()));
            api.setExample(responseExample);
            api.setRequests(requestParams);
            api.setResponse(responseParams);
            apis.add(api);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("api", api);
            jsonObject.put("auth", author);
            jsonObject.put("dollar", "$");
            jsonObject.put("sharp", "#");
            jsonObject.put("time", dateFormat);
//            ICxyunClient_java.vm
            VelocityUtil.parse("ModelRequest_java.vm", jsonObject, outDir + "/" + api.getClassName() + "Request.java", fileEngine);
            VelocityUtil.parse("ModelResponse_java.vm", jsonObject, outDir + "/" + api.getClassName() + "Response.java", fileEngine);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("apis", apis);
        jsonObject.put("auth", author);
        jsonObject.put("dollar", "$");
        jsonObject.put("sharp", "#");
        jsonObject.put("time", dateFormat);
        VelocityUtil.parse("CxyunClientService_java.vm", jsonObject, outDir + "/CxyunClientService.java", fileEngine);
        VelocityUtil.parse("ICxyunClient_java.vm", jsonObject, outDir + "/ICxyunClient.java", fileEngine);
    }

    private static List<ShowDocResponseBean> parseResponseParams(Element responseEl) {
        Elements paramsEl = responseEl.getElementsByTag("tbody").get(0).getElementsByTag("tr");
        List<ShowDocResponseBean> list = paramsEl.stream().map(item -> {
            ShowDocResponseBean responseBean = new ShowDocResponseBean();
            Elements itemEl = item.getElementsByTag("td");
            responseBean.setParamName(itemEl.get(0).text());
            responseBean.setType(itemEl.get(1).text());
            responseBean.setComment(itemEl.get(2).text());
            repair(responseBean);
            return responseBean;
        }).collect(Collectors.toList());
        //去重
        for (int i = list.size() -1 ; i >=0 ; i--) {
            for (int j = list.size() -1 ; j >=0 ; j--) {
                if(i == j){
                    continue;
                }
                if(list.get(i).getParamName().equals(list.get(j).getParamName())){
                    list.remove(j);
                }
            }
        }
        return list;
    }

    private static List<ShowDocRequestBean> parseRequestParams(Element requestEl) {
        Elements paramsEl = requestEl.getElementsByTag("tbody").get(0).getElementsByTag("tr");
        List<ShowDocRequestBean> list = paramsEl.stream().map(item -> {
            ShowDocRequestBean requestBean = new ShowDocRequestBean();
            Elements itemEl = item.getElementsByTag("td");
            requestBean.setParamName(itemEl.get(0).text());
            requestBean.setRequired(itemEl.get(1).text());
            requestBean.setType(itemEl.get(2).text());
            requestBean.setComment(itemEl.get(3).text());
            requestBean.setIsSign(itemEl.get(4).text());
            repair(requestBean);
            return requestBean;
        }).collect(Collectors.toList());
        //去重
        for (int i = list.size() -1 ; i >=0 ; i--) {
            for (int j = list.size() -1 ; j >=0 ; j--) {
                if(i == j){
                    continue;
                }
                if(list.get(i).getParamName().equals(list.get(j).getParamName())){
                    list.remove(j);
                }
            }
        }
        return list;
    }


    private static void repair(ShowDocResponseBean requestBean) {
        //修正类型
        if (requestBean.getType().equalsIgnoreCase("json")) {
            requestBean.setRepairType("com.alibaba.fastjson.JSONObject");
        } else if (requestBean.getType().equals("string")) {
            requestBean.setRepairType(Utils.firstUppercase(requestBean.getType()));
        } else if (requestBean.getType().equals("BigDecimal")) {
            requestBean.setRepairType("java.math.BigDecimal");
        } else if (requestBean.getType().equals("List")) {
            requestBean.setRepairType("java.util.List");
        } else {
            requestBean.setRepairType(requestBean.getType());
        }
        //修正必要字段
        if (!requestBean.getParamName().equals("appKey")) {
            requestBean.setUnderLineParamName(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, requestBean.getParamName()));
        } else {
            requestBean.setUnderLineParamName(requestBean.getParamName());
        }
        requestBean.setLowerCamel(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, requestBean.getUnderLineParamName()));
    }

    public static void main(String[] args) throws Exception {
        File dir = new File(System.getProperty("user.dir"), "min-gcode-maven-plugin/src/config/vms");
        File dist = new File(System.getProperty("user.dir"), "min-gcode-maven-plugin/src/config/dist");
        genCode("https://www.showdoc.com.cn", "/1735808258920310", dir.getAbsolutePath(), "唐植超", dist.getAbsolutePath());
    }
}
